/**
 * 
 */
package com.ms.game.itembox;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.ms.game.itembox.container.ItemBasic;
import com.ms.game.itembox.db.PlayerCrystalChangeLogModel;
import com.ms.game.itembox.db.PlayerItemChangeLogModel;
import com.ms.player.PlayerUserType;
import com.ms.player.UpdateAttribute;
import com.ms.service.error.ErrorCode;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.game.utility.GameUtility;
import com.xpec.c4.message.ConstantCode;
import com.xpec.c4.service.module.common.ItemInfoManager;

/**
 * 透過 dc 變更角色道具的相關參數
 * 
 * @author TW15010
 */
public class ItemChangeParam implements Serializable {
	private static final long serialVersionUID = 3493315481373004157L;

	public static final BigDecimal NO_EXP = BigDecimal.ZERO;
	
	/** 交易id */
	private GUID orderId;

	/** 要變更的道具和數值清單 */
	ChangeItemLister changeItemLister;

	/** 遊戲館id(gameType) */
	private String gameHallId;

	/** 遊戲館名(hallType) */
	private String gameHallName;
	
	/**
	 * 幣值比(一般初始狀況都維持1)
	 */
	private BigDecimal gainRate = BigDecimal.ONE;
	public BigDecimal getGainRate() { return gainRate; }
	public void setGainRate(BigDecimal gainRate) { this.gainRate = gainRate; }

	/** 道具行為id */
	private ItemChangeWay changeWay;
	
	/** 水晶行為id */
	private CrystalChangeWay crystalChangeWay;

	/** account guid */
	private GUID accountId;

	/** player guid */
	private GUID playerId;

	/** player name */
	private String playerName;
	
	/** 角色等級*/
	private int playerLevel;
	
	/** 角色vip等級*/
	private int playerVipLevel;
	
	/** 上一次 使用等級寶箱的等級*/
	private int lastLevelBoxUseLevel;

	/** 使用者類型 {@link PlayerUserType} */
	private int userType;

	/** 目標角色的 guid */
	private GUID targetId;

	/** 目標角色的 name */
	private String targetName;

	/** 發出要求的 module id */
	private String srcModuleId;

	/** 是否有獲得水晶*/
	private boolean addCrystal;
	
	/** 玩家身上目前水晶數量*/
	private int crystalBeforeChange;
	
	/** 玩家要增加的水晶數量*/
	private int crystalChangeValue;
	
	/** 玩家變更後的水晶數量*/
	private int crystalAfterChange;
	
	/** 經驗值增加的值 */
	private BigDecimal expChangeValue;
	
	// 返回資料區 ===============================================
	
	/** 角色數值變更後連帶影響的屬性清單 */
	private ArrayList<UpdateAttribute> updatedAttrList;
	
	/** 
	 * 增加的水晶道具卡資訊
	 */
	private ArrayList<Item> crystalCardList = new ArrayList<Item>();
	
	/**
	 * 執行後回傳, 異動過程中如果有產生新道具會存在這裡<br>
	 * key: 道具序號<br>
	 * value: 道具資料
	 */
	private HashMap<String, Item> newItemMap = new HashMap<String, Item>();

	/**
	 * 執行後回傳, 寄送禮物後產生的道具清單<br>
	 * 寄送禮物將可堆疊道具拆分出去可能會產生新的道具序號, 所以另外用一個清單記錄所有寄出的道具資料<br>
	 * String: 道具序號
	 */
	private ArrayList<Item> sendGiftItemList = new ArrayList<Item>();

	/**
	 * 道具異動過程中產生的 log list
	 */
	private ArrayList<PlayerItemChangeLogModel> logModelList = new ArrayList<PlayerItemChangeLogModel>();
	
	/** 水晶 change Log*/
	private PlayerCrystalChangeLogModel crystalChangeLogModel;

	/** 執行後回傳, 結果代碼 */
	private int result;

	/**
	 * 取得 log 用的執行結果字串
	 * <p>
	 * 必須在有執行結果之後才呼叫
	 * 
	 * @return 執行結果字串
	 */
	public String getResultString() {
		StringBuilder sb = new StringBuilder();

		sb.append("change player(" + playerName + "|" + playerId + ") item " + changeWay.getDesc() + " ");

		if (result == ErrorCode.SUCCESS) {
			sb.append("success. ");
		} else {
			sb.append("fail(" + ConstantCode.getName(ErrorCode.class, result) + "). ");
		}

		// 顯示指定異動清單
		ChangeItemLister itemLister = getChangeItemLister();
		Iterator<Map.Entry<String, ChangeItem>> it = itemLister.getListIterator();
		ChangeItem itemInfo = itemLister.getNextItem(it);
		while (itemInfo != null) {
			sb.append(itemInfo.getItemId() + " " + itemInfo.getChangeCount() + " res="
					+ ConstantCode.getName(ErrorCode.class, itemInfo.getResult()) + ". ");

			itemInfo = itemLister.getNextItem(it);
		}
		
		// 顯示實際異動結果
		for (PlayerItemChangeLogModel logModel : logModelList) {
			sb.append(logModel.getItemId() + " " + logModel.getItemName() + " " + logModel.getItemSn() + " "
					+ logModel.getChangeCount() + " " + logModel.getBeforeChange() + " => "
					+ logModel.getAfterChange());
			
			if(GameUtility.isHaveString(logModel.getFromItemSn())){
				sb.append(" from "+logModel.getFromItemSn());
			}
			
			if(GameUtility.isHaveString(logModel.getToItemSn())){
				sb.append(" to "+logModel.getToItemSn());
			}
			
			sb.append(". ");
		}

		sb.append("orderId=" + orderId.toString());

		return sb.toString();
	}
	
	/**
	 * 產生一筆道具異動 log
	 * 
	 * @param itemSn
	 *            道具序號
	 * @param itemId
	 *            道具 id
	 * @param beforeCount
	 *            異動前的數量
	 * @param changeCount
	 *            異動數量
	 * @param afterCount
	 *            異動後的數量
	 * @param fromItemSn
	 *            來源堆疊序號 {@link PlayerItemChangeLogModel#getFromItemSn()}
	 * @param toItemSn
	 *            目的堆疊序號 {@link PlayerItemChangeLogModel#getToItemSn()}
	 * @param refineLevel           
	 * 			      道具等級
	 * @return 產生的 log model
	 */
	public PlayerItemChangeLogModel addLog(String itemSn, String itemId, int beforeCount, int changeCount,
			int afterCount, String fromItemSn, String toItemSn, int refineLevel) {
		// 取得道具名稱
		ItemBasic item = ItemInfoManager.getInstance().getItem(itemId);
		String itemName = "";
		if (item != null) {
			itemName = item.getName();
		}

		// 產生道具 log model
		PlayerItemChangeLogModel model = new PlayerItemChangeLogModel();

		model.setOrderId(orderId.toString());
		model.setAccountId(accountId.toString());
		model.setPlayerId(playerId.toString());
		model.setPlayerName(playerName);
		model.setUserType(userType);
		model.setGameHallId(gameHallId);
		model.setGameHallName(gameHallName);
		model.setChangeWay(changeWay.getId());
		model.setChangeWayDesc(changeWay.getDesc());

		model.setItemSn(itemSn);
		model.setItemId(itemId);
		model.setItemName(itemName);
		model.setRefineLevel(refineLevel);
		model.setChangeCount(changeCount);
		model.setBeforeChange(beforeCount);
		model.setAfterChange(afterCount);

		model.setFromItemSn(fromItemSn);
		model.setToItemSn(toItemSn);

		if (targetId != null) {
			model.setTargetId(targetId.toString());
		}
		model.setTargetName(targetName);

		logModelList.add(model);

		return model;
	}

	/**
	 * 水晶異動的log
	 * @return
	 */
	public PlayerCrystalChangeLogModel addCrystalLog() {
		// 產生水晶 log model
		PlayerCrystalChangeLogModel model = new PlayerCrystalChangeLogModel();

		model.setOrderId(orderId.toString());
		model.setAccountId(accountId.toString());
		model.setPlayerId(playerId.toString());
		model.setPlayerName(playerName);
		model.setModuleId(gameHallId);
		model.setChangeWay(changeWay.getId());
		model.setChangeWayDesc(changeWay.getDesc());

		model.setChangeCrystal(crystalChangeValue);
		model.setBeforeCrystal(crystalBeforeChange);
		model.setAfterCrystal(crystalAfterChange);

		model.setChangeWay(crystalChangeWay.getId());
		model.setChangeWayDesc(crystalChangeWay.getDesc());
		crystalChangeLogModel = model;
		
		return model;
	}

	
	/**
	 * 加入異動過程中新增的道具
	 * 
	 * @param itemSn
	 *            道具序號
	 * @param newItem
	 *            道具資料
	 */
	public void addNewItem(String itemSn, Item newItem) {
		newItemMap.put(itemSn, newItem);
	}

	public String getGameHallId() {
		return gameHallId;
	}

	public void setGameHallId(String gameHallId) {
		this.gameHallId = gameHallId;
	}

	public ItemChangeWay getChangeWay() {
		return changeWay;
	}

	public void setChangeWay(ItemChangeWay changeWay) {
		this.changeWay = changeWay;
	}

	public GUID getAccountId() {
		return accountId;
	}

	public void setAccountId(GUID accountId) {
		this.accountId = accountId;
	}

	public GUID getPlayerId() {
		return playerId;
	}

	public void setPlayerId(GUID playerId) {
		this.playerId = playerId;
	}

	public String getPlayerName() {
		return playerName;
	}

	public void setPlayerName(String playerName) {
		this.playerName = playerName;
	}

	public int getPlayerLevel() {
		return playerLevel;
	}

	public void setPlayerLevel(int playerLevel) {
		this.playerLevel = playerLevel;
	}

	public int getPlayerVipLevel() {
		return playerVipLevel;
	}

	public void setPlayerVipLevel(int playerVipLevel) {
		this.playerVipLevel = playerVipLevel;
	}

	public int getLastLevelBoxUseLevel() {
		return lastLevelBoxUseLevel;
	}

	public void setLastLevelBoxUseLevel(int lastLevelBoxUseLevel) {
		this.lastLevelBoxUseLevel = lastLevelBoxUseLevel;
	}

	public String getSrcModuleId() {
		return srcModuleId;
	}

	public void setSrcModuleId(String srcModuleId) {
		this.srcModuleId = srcModuleId;
	}

	public boolean isAddCrystal() {
		return addCrystal;
	}

	public void setAddCrystal(boolean addCrystal) {
		this.addCrystal = addCrystal;
	}

	public int getCrystalBeforeChange() {
		return crystalBeforeChange;
	}

	public void setCrystalBeforeChange(int crystalBeforeChange) {
		this.crystalBeforeChange = crystalBeforeChange;
	}

	public int getCrystalChangeValue() {
		return crystalChangeValue;
	}

	public void setCrystalChangeValue(int crystalChangeValue) {
		this.crystalChangeValue = crystalChangeValue;
	}

	public int getCrystalAfterChange() {
		return crystalAfterChange;
	}

	public void setCrystalAfterChange(int crystalAfterChange) {
		this.crystalAfterChange = crystalAfterChange;
	}

	public String getGameHallName() {
		return gameHallName;
	}

	public void setGameHallName(String gameHallName) {
		this.gameHallName = gameHallName;
	}

	public int getResult() {
		return result;
	}

	public void setResult(int result) {
		this.result = result;
	}

	public GUID getOrderId() {
		return orderId;
	}

	public void setOrderId(GUID orderId) {
		this.orderId = orderId;
	}

	public ChangeItemLister getChangeItemLister() {
		return changeItemLister;
	}

	public void setChangeItemLister(ChangeItemLister changeItemLister) {
		this.changeItemLister = changeItemLister;
	}

	public GUID getTargetId() {
		return targetId;
	}

	public void setTargetId(GUID targetId) {
		this.targetId = targetId;
	}

	public String getTargetName() {
		return targetName;
	}

	public void setTargetName(String targetName) {
		this.targetName = targetName;
	}

	/**
	 * 新增寄送禮物後產生的道具資料
	 * 
	 * @param item
	 */
	public void addSendGiftItem(Item item) {
		sendGiftItemList.add(item);
	}

	public ArrayList<Item> getSendGiftItemList() {
		return sendGiftItemList;
	}

	public void setSendGiftItemList(ArrayList<Item> sendGiftItemList) {
		this.sendGiftItemList = sendGiftItemList;
	}

	public HashMap<String, Item> getNewItemMap() {
		return newItemMap;
	}

	public void setNewItemMap(HashMap<String, Item> newItemMap) {
		this.newItemMap = newItemMap;
	}

	public ArrayList<PlayerItemChangeLogModel> getLogModelList() {
		return logModelList;
	}

	public void setLogModelList(ArrayList<PlayerItemChangeLogModel> logModelList) {
		this.logModelList = logModelList;
	}

	public int getUserType() {
		return userType;
	}

	public void setUserType(int userType) {
		this.userType = userType;
	}

	public ArrayList<Item> getCrystalCardList() {
		return crystalCardList;
	}

	public void setCrystalCardList(ArrayList<Item> crystalCardList) {
		this.crystalCardList = crystalCardList;
	}

	public PlayerCrystalChangeLogModel getCrystalChangeLogModel() {
		return crystalChangeLogModel;
	}

	public void setCrystalChangeLogModel(PlayerCrystalChangeLogModel crystalChangeLogModel) {
		this.crystalChangeLogModel = crystalChangeLogModel;
	}

	public CrystalChangeWay getCrystalChangeWay() {
		return crystalChangeWay;
	}

	public void setCrystalChangeWay(CrystalChangeWay crystalChangeWay) {
		this.crystalChangeWay = crystalChangeWay;
	}

	public BigDecimal getExpChangeValue() {
		return expChangeValue;
	}

	public void setExpChangeValue(BigDecimal expChangeValue) {
		this.expChangeValue = expChangeValue;
	}

	public ArrayList<UpdateAttribute> getUpdatedAttrList() {
		return updatedAttrList;
	}

	public void setUpdatedAttrList(ArrayList<UpdateAttribute> updatedAttrList) {
		this.updatedAttrList = updatedAttrList;
	}
}
